﻿using System;
using System.Collections.Specialized;
using System.Web.Security;

namespace SubSonic.Security{

    public class MemProviderConfig{

        public MemProviderConfig(NameValueCollection config){
            //REQUIRES UNIQUE EMAIL
            this.RequiredUniqueEmail = GetBool("requiresUniqueEmail", config);
            config.Remove("requiresUniqueEmail");

            //CACHE USER INFO
            this.CacheUserInfo = GetBool("cacheUserInfo", config);
            config.Remove("cacheUserInfo");

            //PASSWORD STRENGTH
            this.PasswordStength = config["passwordStrength"];
            config.Remove("passwordStrength");

            //REQUIRES Q&A
            this.RequiresQuestionAndAnswer = GetBool("requiresQuestionAndAnswer", config);
            config.Remove("requiresQuestionAndAnswer");

            //MAX PASS ATTEMPTS
            this.MaxInvalidPasswordAttempts = GetInt("MaxInvalidPasswordAttempts", config, 10);
            config.Remove("MaxInvalidPasswordAttempts");

            //NON-ALPHA CHARACTERS
            this.MinRequiredNonAlphanumericCharacters = GetInt("MinRequiredNonAlphanumericCharacters", config, 0);
            config.Remove("MinRequiredNonAlphanumericCharacters");

            //MIN PASS LENGTH
            this.MinRequiredPasswordLength = GetInt("MinRequiredPasswordLength", config, 5);
            config.Remove("MinRequiredPasswordLength");


            //PASSWORD ATTEMPT WINDOW
            this.PasswordAttemptWindow = GetInt("PasswordAttemptWindow", config, 10);
            config.Remove("PasswordAttemptWindow");


            //APPLICATION NAME
            this.ApplicationName = config["ApplicationName"];
            config.Remove("ApplicationName");

            //PASSWORD FORMAT
            this.PasswordFormat = ConvertToFormat(config["PasswordFormat"]);
            config.Remove("PasswordFormat");


            //ENABLE PASS Retrieval
            this.EnablePasswordRetrieval = GetBool("EnablePasswordRetrieval", config);
            config.Remove("EnablePasswordRetrieval");


            //CLEANUP
            /*If config.Count > 0 Then
                Dim key As String = config.GetKey(0)
                If Not String.IsNullOrEmpty(key) Then
                    Throw New ProviderException("Unrecognized provider attribute: " & key)
                End If
            End If*/

        }

        #region Methods
        /// <summary>
        /// Converts string to PasswordFormat
        /// </summary>
        /// <param name="configValue">String representation of PasswordFormat</param>
        /// <returns>MembershipPasswordFormat</returns>
        public static System.Web.Security.MembershipPasswordFormat ConvertToFormat(string configValue){
            switch (configValue.ToLower()){
                case "clear":
                    return System.Web.Security.MembershipPasswordFormat.Clear;
                case "encrypted":
                    return System.Web.Security.MembershipPasswordFormat.Encrypted;
                case "c":
                    return MembershipPasswordFormat.Clear;
                case "h":
                    return MembershipPasswordFormat.Hashed;
                case "e":
                    return MembershipPasswordFormat.Encrypted;
                default:
                    return System.Web.Security.MembershipPasswordFormat.Hashed;
            }
        }

        /// <summary>
        /// Converts configuration value from
        /// String into an integer
        /// (Goes to default when invalid)
        /// </summary>
        /// <param name="keyVal">Expected config name</param>
        /// <param name="config">Serialized Membership configuration section</param>
        /// <param name="defaultValue">Default integer</param>
        /// <returns>Integer representation of config value</returns>
        private static int GetInt(string keyVal, NameValueCollection config, int defaultValue){
            //CONVERSION NOTE: For the C# to VB conversion, don't use Int32.TryParse
            
            string paw = config[keyVal];
            int retint;
            if (string.IsNullOrEmpty(paw) || Int32.TryParse(paw, out retint) == false)
                retint = defaultValue;

            return retint;
        }

        /// <summary>
        /// Converts configuration value from
        /// String into an boolean
        /// ([Default] is false)
        /// </summary>
        /// <param name="keyVal">Expected config name</param>
        /// <param name="config">Serialized Membership configuration section</param>
        /// <returns>Boolean converted from string</returns>
        private static bool GetBool(string keyVal, NameValueCollection config){
            //CONVERSION NOTE: For the C# to VB conversion, don't use bool.TryParse
            bool retVal = false;
            bool.TryParse(config[keyVal], out retVal);
            return retVal;
        }


        #endregion

        #region Props

        private bool _requiredUniqueEmail = true;
        public bool RequiredUniqueEmail{
            get { return _requiredUniqueEmail; }
            set { _requiredUniqueEmail = value; }
        }

        private bool _cacheuserinfo = false;
        public bool CacheUserInfo{
            get { return _cacheuserinfo; }
            set { _cacheuserinfo = value; }
        }

        private string _passwordstength = string.Empty;
        public string PasswordStength{
            get { return _passwordstength; }
            set { _passwordstength = value; }
        }


        private bool _requiresqanda = true;
        public bool RequiresQuestionAndAnswer{
            get { return _requiresqanda; }
            set { _requiresqanda = value; }
        }

        private int _MaxInvalidPasswordAttempts = 10;
        public int MaxInvalidPasswordAttempts{
            get { return _MaxInvalidPasswordAttempts; }
            set { _MaxInvalidPasswordAttempts = value; }
        }


        private int _MinRequiredNonAlphanumericCharacters = 0;
        public int MinRequiredNonAlphanumericCharacters{
            get { return _MinRequiredNonAlphanumericCharacters; }
            set { _MinRequiredNonAlphanumericCharacters = value; }
        }

        private int _MinRequiredPasswordLength = 6;
        public int MinRequiredPasswordLength{
            get { return _MinRequiredPasswordLength; }
            set { _MinRequiredPasswordLength = value; }
        }

        private int _PasswordAttemptWindow = 10;
        public int PasswordAttemptWindow{
            get { return _PasswordAttemptWindow; }
            set { _PasswordAttemptWindow = value; }
        }

        private string _applicationame = string.Empty;
        public string ApplicationName{
            get { return _applicationame; }
            set { _applicationame = value; }
        }

        private bool _EnablePasswordRetrieval = false;
        public bool EnablePasswordRetrieval{
            get { return _EnablePasswordRetrieval; }
            set { _EnablePasswordRetrieval = value; }
        }

        private System.Web.Security.MembershipPasswordFormat _PassFormat = System.Web.Security.MembershipPasswordFormat.Hashed;
        public System.Web.Security.MembershipPasswordFormat PasswordFormat{
            get { return _PassFormat; }
            set { _PassFormat = value; }
        }

        #endregion
    }
}
